package cn.lisens.common.dict;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;

import cn.lisens.common.annotation.DictEnum;
import cn.lisens.common.dict.model.DictData;
import cn.lisens.common.dict.model.DictType;
import cn.lisens.common.enums.CodedEnum;

@Component
public class DictScanner implements ResourceLoaderAware {

	private List<DictType> dictTypeList = new ArrayList<>();
	private ResourceLoader resourceLoader;
	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	private ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
	private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
	private static final String FULLTEXT_SACN_PACKAGE_PATH = "cn.lisens";
	
	
	@PostConstruct
	private void init() {
		doScan();
	}
	
	private void doScan() {
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
				.concat(ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(FULLTEXT_SACN_PACKAGE_PATH))
				.concat("/**/*.class"));
		try {
			Resource[] resources = resolver.getResources(packageSearchPath);
			MetadataReader metadataReader = null;
			for (Resource resource : resources) {
				if (resource.isReadable()) {
					metadataReader = metadataReaderFactory.getMetadataReader(resource);
					if (metadataReader.getClassMetadata().isFinal()) {// 当类型不是抽象类或接口在添加到集合
                    	Class<?> clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
                    	DictEnum enumCode = clazz.getAnnotation(DictEnum.class);
                    	if(null != enumCode) {
                    		DictType model = handleDictEnum(clazz, enumCode);
                    		dictTypeList.add(model);
                    	}
                    }
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("字典扫描失败");
		}
	}
	/**
	 * 处理字典枚举类
	 * @param clazz
	 * @param enumCode
	 * @return
	 */
	private DictType handleDictEnum(Class<?> clazz, DictEnum enumCode) {
		DictType dictType = new DictType();
		dictType.setDictName(enumCode.name());
		dictType.setDictType(enumCode.key());
		List<DictData> datas = new ArrayList<>();
		dictType.setDatas(datas);
		Arrays.stream(clazz.getEnumConstants()).forEach(item->{
			DictData dictData = new DictData();
			CodedEnum codedEnum = (CodedEnum)item;
			dictData.setDictLabel(codedEnum.getMessage());
//			dictData.setDictValue(codedEnum.toString());
			dictData.setDictValue(codedEnum.getCode().toString());
			datas.add(dictData);
		});
		return dictType;
	}
	
	public List<DictType> getDictTypeList() {
		return dictTypeList;
	}
}
